﻿#include "SilverCore.h"
#include <QtCore/QEvent>
#include "app.h"

//构造函数
SilverCore::SilverCore(QWidget *parent)
	: QDialog(parent) {
	Qt::WindowFlags flags = Qt::Dialog;
	flags |= Qt::WindowMinMaxButtonsHint;
	flags |= Qt::WindowCloseButtonHint;
	setWindowFlags(flags);
	ui.setupUi(this);
	
	//取消开发者模式的可见
	ui.developGroup->setVisible(false);

	//初始化QtAwesome
	_awesome = new QtAwesome();
	_awesome->initFontAwesome();
	//设置导航按键图标
	setNavBtnIcon(ui.dataDisplayBtn, fa::barchart);
	setNavBtnIcon(ui.curvesDisplayBtn, fa::areachart);
	setNavBtnIcon(ui.configBtn, fa::cogs);
	setNavBtnIcon(ui.calibrateBtn, fa::balancescale);
	setNavBtnIcon(ui.firmwareBtn, fa::clouddownload);
	setNavBtnIcon(ui.expandBtn, fa::plussquare);

	//设置普通按键图标
	QVariantMap optionsBtn;
	optionsBtn.insert("color", QColor(0x94ffff));
	optionsBtn.insert("color-active", QColor(0x94ffff));
	ui.clearBtn->setIcon(_awesome->icon(fa::trash, optionsBtn));
	ui.refreshBtn->setIcon(_awesome->icon(fa::refresh, optionsBtn));
	optionsBtn.insert("text-off", QString(fa::link));
	optionsBtn.insert("color-disabled", QColor(Qt::black));
	ui.connectBtn->setIcon(_awesome->icon(fa::unlink, optionsBtn));

	//初始化配置文件
	InitMainWindowConfig();

	//创建连接对象
	_connectThread = new ConnectThread();

	//创建配置表
	_config = new Config(_connectThread);

	//创建子页面
	_dataWidget = new DataWidget();
	_plotWidget = new PlotWidget(_settings);
	_configWidget = new ConfigWidget(_connectThread, _config, _settings);
	_calibrateWidget = new CalibrateWidget(_connectThread, _config);
	_firmwareWidget = new FirmwareWidget(_connectThread, _config);
	_expandWidget = new ExpandWidget();

	//添加开发者模式的链接
	createJsonControlMapping();

	//添加子页面到主窗口
	ui.stackedWidget->insertWidget(0, _dataWidget);
	ui.stackedWidget->insertWidget(1, _plotWidget);
	ui.stackedWidget->insertWidget(2, _configWidget);
	ui.stackedWidget->insertWidget(3, _calibrateWidget);
	ui.stackedWidget->insertWidget(4, _firmwareWidget);
	ui.stackedWidget->insertWidget(5, _expandWidget);

	//绑定串口的错误信息提示
	QObject::connect(_connectThread, SIGNAL(error(QString)), this, SLOT(handleSerialError(QString)));
	//绑定连接与配置页面的enable
	QObject::connect(this, SIGNAL(setConnectControlEnable(bool)), _plotWidget, SLOT(setCurvesReload(bool)));
	QObject::connect(this, SIGNAL(setConnectControlEnable(bool)), _configWidget, SLOT(setGetConfigEnable(bool)));
	QObject::connect(this, SIGNAL(setConnectControlEnable(bool)), _calibrateWidget, SLOT(setAllControlEnable(bool)));
	QObject::connect(this, SIGNAL(setConnectControlEnable(bool)), _firmwareWidget, SLOT(setGetVersionEnable(bool)));

	qRegisterMetaType<uint64_t>("uint64_t");
	QObject::connect(_connectThread, SIGNAL(displayTxNum(uint64_t)), this, SLOT(displayTxNum(uint64_t)));
	QObject::connect(_connectThread, SIGNAL(displayRxNum(uint64_t)), this, SLOT(displayRxNum(uint64_t)));
	QObject::connect(ui.clearBtn, SIGNAL(clicked()), _dataWidget, SLOT(clearTx()));
	QObject::connect(ui.clearBtn, SIGNAL(clicked()), _dataWidget, SLOT(clearRx()));
	//各个窗口和主窗口的操作记载
	qRegisterMetaType<fa::icon>("fa::icon");
	QObject::connect(_dataWidget, SIGNAL(operationRecord(fa::icon, QString)), this, SLOT(operationRecord(fa::icon, QString)));
	QObject::connect(_plotWidget, SIGNAL(operationRecord(fa::icon, QString)), this, SLOT(operationRecord(fa::icon, QString)));
	QObject::connect(_configWidget, SIGNAL(operationRecord(fa::icon, QString)), this, SLOT(operationRecord(fa::icon, QString)));
	QObject::connect(_calibrateWidget, SIGNAL(operationRecord(fa::icon, QString)), this, SLOT(operationRecord(fa::icon, QString)));
	QObject::connect(_firmwareWidget, SIGNAL(operationRecord(fa::icon, QString)), this, SLOT(operationRecord(fa::icon, QString)));
	QObject::connect(_expandWidget, SIGNAL(operationRecord(fa::icon, QString)), this, SLOT(operationRecord(fa::icon, QString)));

	//重连函数
	QObject::connect(_configWidget, SIGNAL(reConnectPort(bool, bool)), this, SLOT(connectPort(bool, bool)));
	QObject::connect(_firmwareWidget, SIGNAL(reConnectPort(bool, bool)), this, SLOT(connectPort(bool, bool)));
	//创建port
	_serialport = new QSerialPort(this);
	emit ui.refreshBtn->clicked();
	emit ui.rateSelectBox->activated(ui.rateSelectBox->itemText(2));
	if (ui.portSelectBox->count() > 0) {
		emit ui.portSelectBox->activated(ui.portSelectBox->itemText(0));
	}
}

//析构函数
SilverCore::~SilverCore() {

}

//开发者模式的控件映射
void SilverCore::createJsonControlMapping() {
	_config->setJsonDirControl("/develop/tem-pid/p", ui.p_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/i", ui.i_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/d", ui.d_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/f", ui.f_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/pm", ui.pm_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/im", ui.im_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/dm", ui.dm_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/tem-pid/om", ui.om_DoubleSpin, JsonDirContent::allResponse);

	_config->setJsonDirControl("/develop/ukf/accelBiasQ", ui.accelBiasQ_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/gyroBiasQ", ui.gyroBiasQ_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/quatQ", ui.quatQ_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/accelBiasV", ui.accelBiasV_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/gyroBiasV", ui.gyroBiasV_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/rateV", ui.rateV_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/accelN", ui.accelN_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/distN", ui.distN_DoubleSpin, JsonDirContent::allResponse);
	_config->setJsonDirControl("/develop/ukf/magN", ui.magN_DoubleSpin, JsonDirContent::allResponse);
}

//组合按键响应
void SilverCore::keyPressEvent(QKeyEvent *event) {
	//召唤开发者界面
	if ((event->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_D)) {
		bool visable = ui.developGroup->isVisible();
		if (false == visable) {
			retry:
			bool ok;
			QString text = QInputDialog::getText(this, tr("开发者模式"), tr("请输入开发者密码"), QLineEdit::Password, 0, &ok);
			if (ok) {
				if (!text.isEmpty()) {
					if (text == "__develop") {
						visable = true;
						ui.developGroup->setVisible(visable);
						_config->sendJsonDirValue("/system/develop", &visable);
						//获取开发者配置信息
						_config->getJsonDirValue("/develop/");
					}
					else {
						//弹出警告窗口
						QMessageBox::warning(this, tr("密码错误"), tr("请重新输入"));
						goto retry;
					}
				}
				else {
					//弹出警告窗口
					QMessageBox::warning(this, tr("密码错误"), tr("请重新输入"));
					goto retry;
				}
			}
		}
		else {
			visable = false;
			ui.developGroup->setVisible(visable);
			_config->sendJsonDirValue("/system/develop", &visable);
		}
	}
}

//配置初始化
void SilverCore::InitMainWindowConfig() {
	_settings = new QSettings("SliverCoreOption.ini", QSettings::IniFormat);
	//读取ini
	QString baudrateStr = _settings->value("SerialPort/baudrate").toString();
	if (baudrateStr != "") {
		ui.rateSelectBox->setCurrentText(QString("%1").arg(baudrateStr));
	}
	else {
		//写入ini配置文件
		_settings->beginGroup("SerialPort");
		_baudrate = ui.rateSelectBox->currentText().toULong();
		_settings->setValue("baudrate", _baudrate);
		_settings->endGroup();
	}
	_baudrate = ui.rateSelectBox->currentText().toULong();
}

//记录操作
void SilverCore::operationRecord(fa::icon icon, QString record) {
	QVariantMap optionsLable;
	optionsLable.insert("color", QColor(Qt::black));
	optionsLable.insert("color-active", QColor(Qt::black));
	ui.tipsIconLabel->setPixmap(_awesome->icon(icon, optionsLable).pixmap(QSize(25, 25)));
	ui.tipsTextLabel->setText(QDateTime::currentDateTime().toString("[yyyy.MM.dd hh:mm:ss.zzz] ") + record);
}

//导航按键图标设置函数
void SilverCore::setNavBtnIcon(NavButton *btn, int character) {
	QVariantMap options;
	//初始化颜色
	options.insert("color", QColor(130, 130, 130));
	options.insert("color-active", QColor(130, 130, 130));
	//设置图标
	btn->setIconNormal(_awesome->icon(character, options).pixmap(QSize(40, 30)));

	options.insert("color", QColor(Qt::white));
	options.insert("color-active", QColor(Qt::white));
	btn->setIconHover(_awesome->icon(character, options).pixmap(QSize(40, 30)));
	btn->setIconCheck(_awesome->icon(character, options).pixmap(QSize(40, 30)));
}

//子页面切换槽
void SilverCore::pageSwitch() {
	QString objName = sender()->objectName();
	if (objName == ui.dataDisplayBtn->objectName()) {
		ui.stackedWidget->setCurrentIndex(0);
	}
	else if (objName == ui.curvesDisplayBtn->objectName()) {
		ui.stackedWidget->setCurrentIndex(1);
	}
	else if (objName == ui.configBtn->objectName()) {
		ui.stackedWidget->setCurrentIndex(2);
	}
	else if (objName == ui.calibrateBtn->objectName()) {
		ui.stackedWidget->setCurrentIndex(3);
	}
	else if (objName == ui.firmwareBtn->objectName()) {
		ui.stackedWidget->setCurrentIndex(4);
	}
	else if (objName == ui.expandBtn->objectName()) {
		ui.stackedWidget->setCurrentIndex(5);
	}
}

//清除串口缓存的槽
void SilverCore::clearCacheClicked(){
	_connectThread->setTxLength(0);
	displayTxNum(_connectThread->getTxLength());
	_connectThread->setRxLength(0);
	displayRxNum(_connectThread->getRxLength());
	operationRecord(fa::trash, tr("清除缓存"));
	emit _plotWidget->clearCurves();
}

//刷新串口的槽
void SilverCore::refreshPortClicked() {
	ui.portSelectBox->clear();
	if (QSerialPortInfo::availablePorts().length() == 0) {
		operationRecord(fa::warning, tr("没有找到端口"));
		//弹出警告窗口
		QMessageBox::warning(this,
			"警告",
			"当前没有找到合适的端口");
		ui.connectBtn->setEnabled(false);
		return;
	}
	operationRecord(fa::searchplus, tr("搜索到%1个端口").arg(QSerialPortInfo::availablePorts().length()));
	foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
		_serialport->setPort(info);
		if (_serialport->open(QIODevice::ReadWrite)) {
			//添加串口到最后combobox
			ui.portSelectBox->addItem(info.portName());
			_serialport->close();
		}
		ui.connectBtn->setEnabled(true);
	}
	if (ui.portSelectBox->count() > 0) {
		emit ui.portSelectBox->activated(ui.portSelectBox->itemText(0));
	}
}

//选择串口波特率的槽
void SilverCore::selectSpeedChanged(QString rate) {
	_baudrate = rate.toULong();
	//qt写入ini配置文件
	_settings->beginGroup("SerialPort");
	_baudrate = ui.rateSelectBox->currentText().toULong();
	_settings->setValue("baudrate", _baudrate);
	_settings->endGroup();
	//记录log
	operationRecord(fa::gear, tr("选择") + rate + tr("bps"));
}

//选择串口号的槽
void SilverCore::selectPortChanged(QString port) {
	_portName = port;
	operationRecord(fa::gear, tr("选择") + port + tr("端口"));
}

//串口打开失败或中断的处理函数
void SilverCore::handleSerialError(QString tips) {
	//弹出警告窗口
	QMessageBox::warning(this, "错误", tips);
	//将ui切换回未连接状态
	connectPort(false, true);
}

//设备连接的ui处理
void SilverCore::connectPort(bool enable, bool init) {
	ui.rateSelectBox->setEnabled(!enable);
	ui.portSelectBox->setEnabled(!enable);
	ui.refreshBtn->setEnabled(!enable);
	ui.connectBtn->setChecked(!enable);
	if (init) {
		emit setConnectControlEnable(enable);
	}
	if (enable) {
		ui.connectBtn->setText(tr("断开连接"));
		operationRecord(fa::link, tr("连接设备"));
	}
	else {
		ui.connectBtn->setText(tr("连接设备"));
		operationRecord(fa::unlink, tr("断开连接"));
	}
}

//slot:显示发送数量
void SilverCore::displayTxNum(uint64_t length) {
	ui.TxNumLabel->setText(QString::number(length));
}

//slot:显示接收数量
void SilverCore::displayRxNum(uint64_t length) {
	ui.RxNumLabel->setText(QString::number(length));
}

//连接串口的槽
void SilverCore::connectComClicked() {
	bool enable = (ui.connectBtn->text() == tr("连接设备"));
	if (enable) {
		_connectThread->openPort(_portName, _baudrate);
	}
	else {
		_connectThread->stop();
	}
	connectPort(enable, true);
}

